import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.nio.charset.StandardCharsets;

// puttytel: Raw connection
public class TelnetServer {
	private static final byte[] crln = new byte[]{'\r', '\n'};

	private static void doLine(byte[] buf, int off, int len, OutputStream os) throws IOException {
		System.out.print("recv [" + len + "]:");
		for (int i = off; i < len; i++)
			System.out.format(" %02X", buf[off + i] & 0xff);
		System.out.println();
		System.out.println(new String(buf, off, len, StandardCharsets.UTF_8));
		os.write(buf, off, len);
		os.write(crln);
	}

	public static void main(@SuppressWarnings("unused") String[] args) throws IOException {
		final int port = 8023;
		try (final var ss = new ServerSocket(port)) {
			System.out.println("telnet listen port: " + port);
			//noinspection InfiniteLoopStatement
			for (final var buf = new byte[65536]; ; ) {
				try (final var s = ss.accept()) {
					System.err.println("accept: " + s.getInetAddress());
					final var is = s.getInputStream();
					final var os = s.getOutputStream();
					int i = 0, j = 0, k, e, n;
					for (; (n = is.read(buf, j, buf.length - j)) > 0; i = 0) {
						System.out.println("<" + n + ">");
						for (k = j, e = j + n; k < e; k++) {
							if (buf[k] == '\n') {
								final int t = k;
								while (i < k && buf[k - 1] == '\r')
									k--;
								doLine(buf, i, k - i, os);
								i = (k = t) + 1;
							}
						}
						j = k - i;
						if (i > 0 && j > 0) {
							if (j >= buf.length)
								throw new IllegalStateException("line overflow");
							System.arraycopy(buf, i, buf, 0, j);
						}
					}
					System.err.println("closed: " + n + ", " + j);
				} catch (Exception e) {
					//noinspection CallToPrintStackTrace
					e.printStackTrace();
				}
			}
		}
	}
}
